#include <msp430.h>
#include <stdio.h>

#define TX	0x02			// txd on P1.1
#define RX	0x04			// rxd on P1.2

// Conditions for 9600 Baud SW UART, SMCLK = 1MHz
#define UART_TBIT_DIV_2     (1000000 / (9600 * 2))
#define UART_TBIT           (1000000 / 9600)

bool DEBUG = true;				// boolean variable for debugging
										// print off extra useful information 

// global variables for working within interrupts
// Now you're thinking in Parallel
unsigned char txData;			// internal global for TX
unsigned char rxData;			// internal global for RX
unsigned char xbeeCount;		// count for rx counting
unsigned char xbeeData[20];	// array for Xbee data, 20 should be ore than enough
unsigned char packetLength;		// variable for packet length used in server communication
unsigned char checkSum;			// variable used for the checksum in server communication 

bool packetRx;						// boolean for packet rx


void init(void);
void txChar(unsigned char data);
void serverSend(unsigned char data);
void print(char *string);

// This function accepts a pointer, typically to a string array
// and prints it out to the uart via the tx buffer
void print(char *string)
{
	while(*string)
	{
		while(!(UCA0IFG&UCTXIFG));		// wait for the buffer to be cleared
		UCA0TXBUF = *string++;			// send the next character and increment pointer 
	}
}

// this is like the print function, but transmits only a single character
void txChar(unsigned char txDat)
{
	while(!(UCA0IFG&UCTXIFG));		// wait for tx buffer to be emptied
	UCA0TXBUF = txDat;				// move new tx data to buffer		
}

// takes a character string, corresponding to a data packet for the server
// and formats the data into a Mage complient packet for communication over the server.
void serverSend(char *data)
{
	packetLength = sizeof(*data) + 9;
	checkSum = 0xFF - packetLength;
	if(DEBUG)
	{
		print("Sending data to server\r\n");
		print("Packet lenght is: ");
		txChar(packetLength);
		txChar('\n');
		print("Check sum is: ");
		txChar(checkSum);
		txChar('\n');
	}

	txChar(0x7E);
	txChar(0x00);
	txChar(packetLength);   // length
	txChar(0x01);   // Frame ID
	txChar(0x01);   // Response Frame can be whatever according to Wira...
	txChar(0xFF);   // Broadcast 0xFFFF
	txChar(0xFF);   // ...
	txChar(0x00);   // options... whatever
	txChar(0xFF);   // mage server address
	txChar(0xFF);   // mage server address
	txChar(0x88);   // our address 8888
	txChar(0x88);   // our address
	// here go our data
	while(*data)
		txChar(*data++);
	txChar(checkSum);   // Checksum
}
void init(void)
{
	P1SEL |= BIT1+BIT2;					// P1.1,2 = USCI_A0 TXD/RXD
	UCA0CTL1 |= UCSWRST;					// **Put state machine in reset**
	UCA0CTL1 |= UCSSEL_2;				// SMCLK
	UCA0BR0 = 104;							// 1MHz 115200 (see User's Guide)
	UCA0BR1 = 0;							// 1MHz 115200
	UCA0MCTL |= UCBRS_1 + UCBRF_0;	// Modulation UCBRSx=1, UCBRFx=0
	UCA0CTL1 &= ~UCSWRST;				// **Initialize USCI state machine**
	UCA0IE |= UCRXIE;						// Enable USCI_A0 RX interrupt
}

// Timer_A UART - Receive Interrupt Handler
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
	switch(__even_in_range(UCA0IV,4))
	{
		case 0:break;                             // Vector 0 - no interrupt
		case 2:                                   // Vector 2 - RXIFG
			while (!(UCA0IFG&UCTXIFG));            // USCI_A0 TX buffer ready?
			if(!packet)	// if not in middle of packet (new data packet)
			{
				packetRx = true;
				rxLength = UCRXIE;	// first byte received is length
				packetPt = 0;		//	set position to be first
			}
			else if(packetPt < rxLength)	// else we in the middle of receiveing a packet
			{
				rxPacket[packetPt++] = UCRXIE;	// next position in rx array gets the data
				if(packetPt = rxLength)			// if we are at the end of the packet then reset the bool variable
					packet = false;				// thinking in terms of interrupts is annoying...
			}	
			break;
		case 4:break;                             // Vector 4 - TXIFG
		default: break;
	}
}
